/*!
 * \file ActionPolicyMgr.cpp
 * \project	WonderTrader
 *
 * \author Wesley
 * \date 2020/03/30
 * 
 * \brief UFT动作策略管理器实现文件
 * 
 * \details 实现超高频交易系统中的动作策略管理功能：
 *          - 策略规则配置文件解析
 *          - 动作类型识别和规则加载
 *          - 品种过滤器配置管理
 *          - 基于品种的规则查找和匹配
 *          - 默认规则组处理和错误处理
 */
#include "ActionPolicyMgr.h"

#include "../Share/StdUtils.hpp"
#include "../WTSTools/WTSLogger.h"

#include "../Includes/WTSVariant.hpp"
#include "../WTSUtils/WTSCfgLoader.h"

USING_NS_WTP;

/*!
 * \brief ActionPolicyMgr构造函数
 * 
 * \details 初始化动作策略管理器，准备内部数据结构
 */
ActionPolicyMgr::ActionPolicyMgr()
{
}

/*!
 * \brief ActionPolicyMgr析构函数
 * 
 * \details 清理资源，释放策略规则和映射表
 */
ActionPolicyMgr::~ActionPolicyMgr()
{
}

/*!
 * \brief 初始化策略管理器
 * \param filename 配置文件路径
 * \return 初始化成功返回true，失败返回false
 * 
 * \details 从配置文件加载动作策略规则的主要流程：
 *          1. 加载配置文件并解析JSON结构
 *          2. 遍历策略组，解析每个组的动作规则
 *          3. 解析动作类型（open、close、closetoday、closeyestoday）
 *          4. 设置数量限制和规则参数
 *          5. 加载品种过滤器，建立品种到策略组的映射
 */
bool ActionPolicyMgr::init(const char* filename)
{
	WTSVariant* cfg = WTSCfgLoader::load_from_file(filename, true);
	if (cfg == NULL)
		return false;

	auto keys = cfg->memberNames();
	for (auto it = keys.begin(); it != keys.end(); it++)
	{
		const char* gpName = (*it).c_str();
		WTSVariant*	vGpItem = cfg->get(gpName);
		ActionRuleGroup& gp = _rules[gpName];

		WTSVariant* vOrds = vGpItem->get("order");
		if(vOrds != NULL && vOrds->isArray())
		{
			for (uint32_t i = 0; i < vOrds->size(); i++)
			{
				WTSVariant* vObj = vOrds->get(i);
				ActionRule aRule;
				const char* action = vObj->getCString("action");
				uint32_t uLimit = vObj->getUInt32("limit");
				uint32_t uLimitS = vObj->getUInt32("limit_s");
				uint32_t uLimitL = vObj->getUInt32("limit_l");
				if (wt_stricmp(action, "open") == 0)
					aRule._atype = AT_Open;
				else if (wt_stricmp(action, "close") == 0)
					aRule._atype = AT_Close;
				else if (wt_stricmp(action, "closetoday") == 0)
					aRule._atype = AT_CloseToday;
				else if (wt_stricmp(action, "closeyestoday") == 0)
					aRule._atype = AT_CloseYestoday;
				else 
				{
					//原始乱码注释：加载平仓策略失败: 未识别的开平仓类型%s
					WTSLogger::error("Loading action policy failed: unrecognized type %s", action);
					continue;
				}

				aRule._limit = uLimit;
				aRule._limit_s = uLimitS;
				aRule._limit_l = uLimitL;
				aRule._pure = vObj->getBoolean("pure");
				gp.emplace_back(aRule);
			}
		}

		WTSVariant* filters = vGpItem->get("filters");
		if(filters!=NULL && filters->isArray() && filters->size()>0)
		{
			for (uint32_t i = 0; i < filters->size(); i++)
			{
				const char* commid = filters->get(i)->asCString();
				_comm_rule_map[commid] = gpName;
			}
		}
	}

	cfg->release();
	return true;
}

/*!
 * \brief 获取指定品种的动作规则组
 * \param pid 品种ID或合约代码
 * \return 返回对应的动作规则组引用
 * 
 * \details 规则查找的完整流程：
 *          1. 默认使用"default"策略组
 *          2. 在品种规则映射表中查找特定品种的策略组
 *          3. 如果找到特定策略组，使用该组名称
 *          4. 在策略规则映射中查找对应的规则组
 *          5. 如果找不到，回退到"default"组并记录错误
 *          6. 返回最终确定的规则组引用
 */
const ActionRuleGroup& ActionPolicyMgr::getActionRules(const char* pid)
{
	std::string gpName = "default";

	{//查找品种对应的规则组名称
		auto it = _comm_rule_map.find(pid);
		if (it != _comm_rule_map.end())
			gpName = it->second;
	}

	{
		auto it = _rules.find(gpName);
		if (it == _rules.end())
		{
			it = _rules.find("default");
			//原始乱码注释：加载平仓策略%s不存在, 自动切换到默认规则组
			WTSLogger::error("Action policy group %s not exists, changed to default group", gpName.c_str());
		}

		assert(it != _rules.end());
		return it->second;
	}
}
